﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Dynamic;
using System.Transactions;
using PagedList;
using Sovigaz.DataProvider;
using Utilities;

namespace Sovigaz.Permission.Repositories
{
    public class UserRepository : GenericRepository
    {
        public UserRepository()
            : base("UserID")
        {
        }

        public ICollection<User> Users { get; set; }

        

        public void Delete(int id)
        {
            var role = GetByID(id);
            if (role != null)
                role.IsDeleted = true;

            _context.SaveChanges();
        }

        public void Delete(string[] idArr)
        {
            foreach (var id in idArr)
            {
                var role = GetByID(ConvertUtility.IntParse(id));
                if (role != null)
                    role.IsDeleted = true;
            }

            _context.SaveChanges();
        }

        public int Update(User user)
        {
            var updateUser = new User();

            using (var scope = new TransactionScope())
            {
                if (user.UserID > 0)
                {
                    updateUser = GetByID(user.UserID);
                    if (!Utility.ArrayEqual(updateUser.Tstamp, user.Tstamp))
                        throw ExceptionHelper.CreateHttpResponseException("Dữ liệu đã bị cập nhật bởi người sử dụng khác.");
                }

                string password = !String.IsNullOrWhiteSpace(user.Password) ? Utility.MD5Encrypt(user.Password) : String.Empty;

                updateUser.UserID = user.UserID;
                updateUser.Username = user.Username;
                updateUser.Password = (updateUser.Password == user.Password || updateUser.Password == password) ? updateUser.Password : password;
                updateUser.FullName = user.FullName;
                updateUser.Position = user.Position;
                updateUser.StartDate = user.StartDate;
                updateUser.Description = user.Description;
                updateUser.IsActived = user.IsActived;

                if (updateUser.UserID == 0)
                    _context.Users.Add(updateUser);
                else
                {
                    _context.Database.SqlQuery<UserRole>("sp_UserRole_Delete_ByUserID @UserID"
                        , new SqlParameter { ParameterName = "UserID", Value = updateUser.UserID }).FirstOrDefault();
                }

                foreach (var ur in user.UserRoles)
                {
                    ur.UserID = updateUser.UserID;
                    _context.UserRoles.Add(ur);
                }

                _context.SaveChanges();

                scope.Complete();
            }

            _context.Entry(updateUser).Reload();

            return updateUser.UserID;
        }

        public User GetByID(int id)
        {
            return _context.Users.FirstOrDefault(p => p.UserID == id && !p.IsDeleted);
        }

        public User GetByUsername(string username)
        {      

            return _context.Users.FirstOrDefault(p => p.Username == username && !p.IsDeleted);
        }

        public UserRepository GetList2(string whereClause, string orderBy, string orderDirection, int pageNumber)
        {
            var users = _context.Users.Where(whereClause)
                .OrderBy(String.Format("{0} {1}", orderBy.Trim(), orderDirection.Trim()))
                .ToPagedList(pageNumber, DefaultPageSize);

            TotalItemCount = users.TotalItemCount;
            TotalItemOnPage = users.Count;
            PageCount = users.PageCount;
            PageNumber = users.PageNumber;
            Users = users.ToList();

            return this;
        }

        public UserRepository GetList(string whereClause, string orderBy, string orderDirection, int pageNumber)
        {
            var users = _context.Users.Where(whereClause)
                .Join(_context.Positions, u => u.Position,p=>p.PositionID,
                (u,p) => new
                {
                    UserID=u.UserID,
                    Username=u.Username,
                    FullName=u.FullName,
                    StartDate=u.StartDate,
                    IsActived=u.IsActived,
                    PositionName=p.PositionName,
                })
                .OrderBy(String.Format("{0} {1}", orderBy.Trim(), orderDirection.Trim()))
                .ToPagedList(pageNumber, DefaultPageSize);

            TotalItemCount = users.TotalItemCount;
            TotalItemOnPage = users.Count;
            PageCount = users.PageCount;
            PageNumber = users.PageNumber;

            Users = new List<User>();
            foreach (var user in users)
            {
                User item=new User();
                item.UserID = user.UserID;
                item.FullName = user.FullName;
                item.Username = user.Username;
                item.StartDate = user.StartDate;
                item.IsActived = user.IsActived;
                item.PositionName = user.PositionName;
                Users.Add(item);
            }            

            return this;
        }

        public List<User> GetListUser(string positionID)
        {
            return _context.Users.Where(p => !p.IsDeleted && p.Position == positionID).ToList();
        }
    }
}
